class Snake{
    constructor(headColor,bodyColor,baseLength){
        this.headColor = headColor;
        this.bodyColor = bodyColor;
        this.baseLength = baseLength;
        this.pos = [];
        this.direction = '';
        this.ground = null;
    }
    /**
     * 创建一条蛇
     * @param {groud} ground 指定创建蛇的场地实例
     */
    create(groundObj){
        if(groundObj.col<=this.baseLength*2||groundObj.row<=this.baseLength*2){
            throw new Error('蛇的初识长度超越了场地的允许范围，蛇长度的两倍应该小与场地的宽高');
        }
        this.ground = groundObj;
        const directions = ['top','right','bottom','left'];
        const snakeHeadCol = ~~(Math.random()*(groundObj.col-this.baseLength*4))+this.baseLength*2;
        const snakeHeadRow = ~~(Math.random()*(groundObj.row-this.baseLength*4))+this.baseLength*2;
        const direction = directions[~~(Math.random()*directions.length)];
        this.pos.push({col:snakeHeadCol,row:snakeHeadRow});
        this.direction = direction;
        let length = 1;
        switch(direction){
            case 'top':
                do{
                    this.pos.push({
                        col:snakeHeadCol+(length++),
                        row:snakeHeadRow
                    });
                }while(length<=this.baseLength)
                break;
            case 'right':
                do{
                    this.pos.push({
                        col:snakeHeadCol,
                        row:snakeHeadRow-(length++)
                    });
                }while(length<=this.baseLength)
                break;
            case 'bottom':
                do{
                    this.pos.push({
                        col:snakeHeadCol-(length++),
                        row:snakeHeadRow
                    });
                }while(length<=this.baseLength)
                break;
            case 'left':
                do{
                    this.pos.push({
                        col:snakeHeadCol,
                        row:snakeHeadRow+(length++)
                    });
                }while(length<=this.baseLength)
                break;
        }
        this.render(this.pos);
    }
    /**
     * 渲染蛇
     */
    render(snakePos){
        document.querySelectorAll('.snake').forEach((snakeNode,index)=>{
            snakeNode.style.backgroundColor = this.ground.bgcolor;
        });
        snakePos.forEach((pos,index)=> {
            this.ground.ground['children'][pos.col]['children'][pos.row].style.backgroundColor = index==0?this.headColor:this.bodyColor;
            this.ground.ground['children'][pos.col]['children'][pos.row].setAttribute('class','snake');
        });
    }
    /**
     * 跑起来
     */
    run(egg){
        let run = setInterval(()=>{
            let pos = JSON.parse(JSON.stringify(this.pos));
            let newPos = pos.map((p,index)=>{
                if(index==0){
                    switch(this.direction){
                        case 'top':
                            p['col'] = p['col']*1 - 1;
                            break;
                        case 'right':
                            p['row'] = p['row']*1 + 1;
                            break;
                        case 'bottom':
                            p['col'] = p['col']*1 + 1;
                            break;
                        case 'left':
                            p['row'] = p['row']*1 - 1;
                            break;
                    }
                    if(p.col == egg.eggCol && p.row == egg.eggRow){
                        this.eat(egg);
                    }
                    return p;
                }else{
                    return this.pos[index-1]
                }
            });
            if(this.eating){
                newPos.push(this.pos[this.pos.length-1]);
                this.eating = false;
            }
            //边界判断
            if(pos[0]['col']<0||pos[0]['col']>this.ground.col-1||pos[0]['row']<0||pos[0]['row']>this.ground.row-1){
                clearInterval(run);
                this.died({
                    msg:'撞墙了'
                });
                return false;
            }
            //吃到自己
            let eatSelf = this.pos.some(item=>{return (item['row']==pos[0]['row']&&item['col']==pos[0]['col'])});
            if(eatSelf){
                clearInterval(run);
                this.died({
                    msg:'吃到自己了'
                });
                return false;
            }
            this.render(newPos);
            this.pos = newPos;
        },100);
        //方向键控制蛇的走向
        document.addEventListener('keydown',event=>{
            switch(event.key){
                case 'ArrowUp':
                    if(this.direction!='top'&&this.direction!='bottom'){
                        this.direction = 'top';
                    }
                    break;
                case 'ArrowDown':
                    if(this.direction!='top'&&this.direction!='bottom'){
                        this.direction = 'bottom';
                    }
                    break;
                case 'ArrowLeft':
                    if(this.direction!='left'&&this.direction!='right'){
                        this.direction = 'left';
                    }
                    break;
                case 'ArrowRight':
                    if(this.direction!='left'&&this.direction!='right'){
                        this.direction = 'right';
                    }
                    break;
            }
        });
    }
    eat(egg){
        this.eating = true;
        egg.create(this.ground,this.pos);
    }
    died(ops){
       alert(ops.msg);
    }
}

export default Snake;